package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author yinxin
 * @version 1.0
 * @Description:
 * @date 2022/6/47:54
 */
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {

    @Bean("threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //线程池维护核心线程数最少数量，没任务执行也会一直存活
        //如果设置AllowCoreThreadTimeOut(默认false)时，核心线程数会超时关闭
        executor.setCorePoolSize(4);
        //阻塞队列的线程数最大值
        executor.setQueueCapacity(32);
        //当阻塞队列存在线程时会创建新线程来执行，当队列满时，线程池会创建新线程来处理任务
        //当线程数满，且阻塞队列满的时候，线程池会拒绝处理任务并抛出异常
        executor.setMaxPoolSize(64);
        //设置新创建的线程空闲时间，时间一过就会销毁
        executor.setKeepAliveSeconds(30);
        executor.setThreadNamePrefix("线程-");
        //阻塞队列拒绝策略
        // rejection-policy：当pool已经达到max size的时候，如何处理新任务
        // CallerRunsPolicy()：交由调用方线程运行，比如 main 线程；如果添加到线程池失败，那么主线程会自己去执行该任务，不会等待线程池中的线程去执行
        //AbortPolicy()：该策略是线程池的默认策略，如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常。
        //DiscardPolicy()：如果线程池队列满了，会直接丢掉这个任务并且不会有任何异常
        //DiscardOldestPolicy()：丢弃队列中最老的任务，队列满了，会将最早进入队列的任务删掉腾出空间，再尝试加入队列
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());

        executor.initialize();
        return executor;
    }
}
